package dilmaj.client;

import java.util.ArrayList;
import java.util.Arrays;
import java.util.Iterator;
import java.util.List;

import com.google.gwt.core.client.GWT;
import com.google.gwt.user.client.rpc.AsyncCallback;
import com.google.gwt.user.client.ui.Label;
import com.google.gwt.user.client.ui.Panel;
import com.google.gwt.user.client.ui.SimplePanel;
import com.google.gwt.user.client.Window;
import com.google.gwt.user.client.ui.PopupPanel;

import dilmaj.shared.StarAreaVO;
import dilmaj.shared.StarCommentVO;
import dilmaj.shared.StarEntryVO;
import dilmaj.shared.StarLanguageVO;
import dilmaj.shared.StarPrivilegeVO;
import dilmaj.shared.StarSourceVO;
import dilmaj.shared.StarSuggestionVO;
import dilmaj.shared.StarTermVO;
import dilmaj.shared.StarUseCaseVO;

public class DataStore {
	private static DilmajConstants constants = GWT.create(DilmajConstants.class);
	
	private static String username=new String("");
	private static long userid=-1;
	
	private static PopupPanel waitPanel=new PopupPanel();
	private static Label waitLabel=new Label(constants.waitMessage());
	
	private static ArrayList<PopupPanel> openPanels=new ArrayList<PopupPanel>();

	private static ArrayList<StarEntryVO> allEntries=new ArrayList<StarEntryVO>();
	private static ArrayList<StarEntryVO> allTerms=new ArrayList<StarEntryVO>();
	private static ArrayList<StarEntryVO> allSuggestions=new ArrayList<StarEntryVO>();
	private static ArrayList<StarEntryVO> allAreas=new ArrayList<StarEntryVO>();
	private static ArrayList<StarEntryVO> allSources=new ArrayList<StarEntryVO>();
	private static ArrayList<StarEntryVO> allLanguages=new ArrayList<StarEntryVO>();
	private static ArrayList<StarEntryVO> allComments=new ArrayList<StarEntryVO>();
	private static ArrayList<StarEntryVO> allUseCases=new ArrayList<StarEntryVO>();
	private static ArrayList<StarEntryVO> allUsers=new ArrayList<StarEntryVO>();
	private static ArrayList<StarEntryVO> allPrivileges=new ArrayList<StarEntryVO>();
	
	private static Object[] allSorted;
	private static Object[] termsSorted;
	private static Object[] suggestionsSorted;
	private static Object[] areasSorted;
	private static Object[] sourcesSorted;
	private static Object[] languagesSorted;
	private static Object[] commentsSorted;
	private static Object[] usecasesSorted;
	private static Object[] privilegesSorted;
	
	private static Object[] termsFound;
	private static Object[] areasFound;
	private static Object[] sourcesFound;
	private static Object[] languagesFound;
	private static Object[] suggestionsFound;
	private static Object[] commentsFound;
	private static Object[] usecasesFound;
	private static Object[] privilegesFound;
	
	private static boolean isChanged=true;

	public static void removeEntry(List<StarEntryVO> entryVOs) {
		Iterator iterator=entryVOs.iterator();
		
		while (iterator.hasNext()) {
			StarEntryVO entryVO=(StarEntryVO)iterator.next();
			if (entryVO!=null) {
				String title=entryVO.getTitle();
				
				allEntries.remove(entryVO);
				
				if (title.compareToIgnoreCase("term")==0) {
					allTerms.remove(entryVO);
				}
				if (title.compareToIgnoreCase("privilege")==0) {
					allPrivileges.remove(entryVO);
				}
				if (title.compareToIgnoreCase("comment")==0) {
					allComments.remove(entryVO);
				}
				if (title.compareToIgnoreCase("usecase")==0) {
					allUseCases.remove(entryVO);
				}
				if (title.compareToIgnoreCase("suggestion")==0) {
					allSuggestions.remove(entryVO);
				}
			}
		}

		allSorted=allEntries.toArray();
		Arrays.sort(allSorted, new EntryComparator());
		  
		termsSorted=allTerms.toArray();
		Arrays.sort(termsSorted, new EntryComparator());
		  
		suggestionsSorted=allSuggestions.toArray();
		Arrays.sort(suggestionsSorted, new EntryComparator());
		  
		commentsSorted=allComments.toArray();
		Arrays.sort(commentsSorted, new EntryComparator());
		  
		usecasesSorted=allUseCases.toArray();
		Arrays.sort(usecasesSorted, new EntryComparator());
		  
		privilegesSorted=allPrivileges.toArray();
	}
	
	public static void setLogin(String userName, long userId) {
		username=userName;
		userid=userId;
		
		Iterator iterator=openPanels.iterator();
		while (iterator.hasNext()) {
			Panel panel=(Panel)iterator.next();
			try {
				StarPanel starPanel=(StarPanel)panel;
				starPanel.refreshLogin();
			} catch (ClassCastException cce0) {
				try {
					StarTablePanel starPanel=(StarTablePanel)panel;
					starPanel.refreshLogin();
				} catch(ClassCastException cce1) {
					
				}
			}
		}
	}
	
	public static String getUsername() {
		return username;
	}
	
	public static long getUserid() {
		return userid;
	}
	
	public static void openPanel(PopupPanel starPanel) {
		openPanels.add(starPanel);
	}

	public static void closePanel(PopupPanel starPanel) {
		openPanels.remove(starPanel);
	}
	
	public static void add(StarEntryVO newEntry) {
		allEntries.add(newEntry);
		allSorted=allEntries.toArray();
		Arrays.sort(allSorted, new EntryComparator());
		
		try {
			StarTermVO termVO=(StarTermVO)newEntry;
			allTerms.add(termVO);
			termsSorted=allTerms.toArray();
			Arrays.sort(termsSorted, new EntryComparator());
		} catch (ClassCastException cce0) {
			try {
				StarSuggestionVO suggestionVO=(StarSuggestionVO)newEntry;
				allSuggestions.add(suggestionVO);
				suggestionsSorted=allSuggestions.toArray();
				Arrays.sort(suggestionsSorted, new EntryComparator());
			} catch (ClassCastException cce1) {
				try {
					StarAreaVO areaVO=(StarAreaVO)newEntry;
					allAreas.add(areaVO);
					areasSorted=allAreas.toArray();
					Arrays.sort(areasSorted, new EntryComparator());
				} catch (ClassCastException cce2) {
					try {
						StarSourceVO sourceVO=(StarSourceVO)newEntry;
						allSources.add(sourceVO);
						sourcesSorted=allSources.toArray();
						Arrays.sort(sourcesSorted, new EntryComparator());
					} catch (ClassCastException cce3) {
						try {
							StarLanguageVO languageVO=(StarLanguageVO)newEntry;
							allLanguages.add(languageVO);
							languagesSorted=allLanguages.toArray();
							Arrays.sort(languagesSorted, new EntryComparator());
						} catch (ClassCastException cce4) {
							try {
								StarCommentVO commentVO=(StarCommentVO)newEntry;
								allComments.add(commentVO);
								commentsSorted=allComments.toArray();
								Arrays.sort(commentsSorted, new EntryComparator());
							} catch (ClassCastException cce5) {
								try {
									StarUseCaseVO usecaseVO=(StarUseCaseVO)newEntry;
									allUseCases.add(usecaseVO);
									usecasesSorted=allUseCases.toArray();
									Arrays.sort(usecasesSorted, new EntryComparator());
								} catch (ClassCastException cce6) {
									try {
										StarPrivilegeVO privilegeVO=(StarPrivilegeVO)newEntry;
										allPrivileges.add(privilegeVO);
										privilegesSorted=allPrivileges.toArray();
										//Arrays.sort(privilegesSorted, new EntryComparator());
									} catch (ClassCastException cce7) {
										
									}
								}
							}
						}
					}
				}
			}
		}
	}
	
	public static boolean hasChanged() {
		return isChanged;
	}
	
	public static void setChanged(boolean changed) {
		isChanged=changed;
	}
	
	private static StarServiceAsync starSvc = GWT.create(StarService.class);

	public static Object[] getSortedPrivileges() {
		return privilegesSorted;
	}

	public static Object[] getSortedSources() {
		return sourcesSorted;
	}

	public static Object[] getSortedLanguages() {
		return languagesSorted;
	}

	public static Object[] getSortedTerms() {
		return termsSorted;
	}

	public static Object[] getSortedAreas() {
		return areasSorted;
	}

	public static Object[] getSortedUseCases() {
		return usecasesSorted;
	}

	public static Object[] getSortedComments() {
		return commentsSorted;
	}

	public static Object[] getSortedSuggestions() {
		return suggestionsSorted;
	}
	
	public static Object[] getFoundPrivileges() {
		return privilegesFound;
	}
	
	public static Object[] getFoundTerms() {
		return termsFound;
	}
	
	public static Object[] getFoundSources() {
		return sourcesFound;
	}
	
	public static Object[] getFoundLanguages() {
		return languagesFound;
	}
	
	public static Object[] getFoundSuggestions() {
		return suggestionsFound;
	}
	
	public static Object[] getFoundAreas() {
		return areasFound;
	}

	public static Object[] getFoundComments() {
		return commentsFound;
	}

	public static Object[] getFoundUseCases() {
		return usecasesFound;
	}

	public static void setFoundPrivileges(Object[] foundPrivileges) {
		privilegesFound=foundPrivileges;
	}

	public static void setFoundComments(Object[] foundComments) {
		commentsFound=foundComments;
	}
	
	public static void setFoundUseCases(Object[] foundUseCases) {
		usecasesFound=foundUseCases;
	}
	
	public static void setFoundSources(Object[] foundSources) {
		sourcesFound=foundSources;
	}
	
	public static void setFoundLanguages(Object[] foundLanguages) {
		languagesFound=foundLanguages;
	}
	
	public static void setFoundTerms(Object[] foundTerms) {
		termsFound=foundTerms;
	}
	
	public static void setFoundSuggestions(Object[] foundSuggestions) {
		suggestionsFound=foundSuggestions;
	}

	public static void setFoundAreas(Object[] foundAreas) {
		areasFound=foundAreas;
	}
	
	static AsyncCallback<List<StarEntryVO>> loadAllStarCallback = new AsyncCallback<List<StarEntryVO>>() {
		  public void onFailure(Throwable caught) {
		        // TODO: Do something with errors.
		  }
	
		  public void onSuccess(List<StarEntryVO> result) {
			  allEntries.clear();
			  allTerms.clear();
			  allSuggestions.clear();
			  allAreas.clear();
			  allLanguages.clear();
			  allSources.clear();
			  allComments.clear();
			  allUseCases.clear();
			  allUsers.clear();
			  allPrivileges.clear();
			  
			  allEntries.addAll(result);
				int termRow=1;
				int suggestionRow=1;
			  
				int i=0;
				  allSorted=allEntries.toArray();
				for (;i<allSorted.length;i++) {
					StarEntryVO entryVO=(StarEntryVO)allSorted[i];//iterator.next();
					if (entryVO!=null) {
						try {
							StarTermVO termVO=(StarTermVO)entryVO;
							allTerms.add(termVO);
						} catch (ClassCastException cce0) {
							try {
								StarSuggestionVO suggestionVO=(StarSuggestionVO)entryVO;
								allSuggestions.add(suggestionVO);
							} catch (ClassCastException cce1) {
								try {
									StarAreaVO areaVO=(StarAreaVO)entryVO;
									allAreas.add(areaVO);
								} catch (ClassCastException cce2) {
									try {
										StarSourceVO sourceVO=(StarSourceVO)entryVO;
										allSources.add(sourceVO);
									} catch (ClassCastException cce3) {
										try {
											StarCommentVO commentVO=(StarCommentVO)entryVO;
											allComments.add(commentVO);
										} catch (ClassCastException cce4) {
											try {
												StarLanguageVO languageVO=(StarLanguageVO)entryVO;
												allLanguages.add(languageVO);
											} catch (ClassCastException cce5) {
												try {
													StarUseCaseVO usecaseVO=(StarUseCaseVO)entryVO;
													allUseCases.add(usecaseVO);
												} catch (ClassCastException cce6) {
													try {
														StarPrivilegeVO privilegeVO=(StarPrivilegeVO)entryVO;
														allPrivileges.add(privilegeVO);
													} catch (ClassCastException cce7) {
														
													}
												}
											}
										}
									}
								}
							}
						}
					}
				}
			  
			  Arrays.sort(allSorted, new EntryComparator());
			  
			  termsSorted=allTerms.toArray();
			  Arrays.sort(termsSorted, new EntryComparator());
			  
			  sourcesSorted=allSources.toArray();
			  Arrays.sort(sourcesSorted, new EntryComparator());
			  
			  languagesSorted=allLanguages.toArray();
			  Arrays.sort(languagesSorted, new EntryComparator());
			  
			  suggestionsSorted=allSuggestions.toArray();
			  Arrays.sort(suggestionsSorted, new EntryComparator());
			  
			  areasSorted=allAreas.toArray();
			  Arrays.sort(areasSorted, new EntryComparator());
			  
			  commentsSorted=allComments.toArray();
			  Arrays.sort(commentsSorted, new EntryComparator());
			  
			  usecasesSorted=allUseCases.toArray();
			  Arrays.sort(usecasesSorted, new EntryComparator());
			  
			  privilegesSorted=allPrivileges.toArray();
			  
			  waitPanel.hide();
		  }
	  };

	public static void installDataStore() {
	    if (starSvc == null) {
		      starSvc = GWT.create(StarService.class);
		    }
	   
	   waitPanel.add(waitLabel);
	   waitPanel.setPopupPosition(Window.getClientWidth()/2, Window.getClientHeight()/2);
	   waitPanel.setModal(true);
	   waitPanel.show();
	   starSvc.loadAll(loadAllStarCallback);
	}
	
	public static void showWait() {
	   waitPanel.show();
	}
	
	public static void hideWait() {
		waitPanel.hide();
	}
}